package com.lzc.jobrecomendbackend.service.overview.impl;

import com.lzc.jobrecomendbackend.model.Job;
import com.lzc.jobrecomendbackend.model.overview.CityOverview;
import com.lzc.jobrecomendbackend.model.overview.HotPosition;
import com.lzc.jobrecomendbackend.model.overview.SummaryVO;
import com.lzc.jobrecomendbackend.model.overview.TotalJobsVO;
import com.lzc.jobrecomendbackend.repository.JobRepository;
import com.lzc.jobrecomendbackend.service.overview.OverviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class OverviewServiceImpl implements OverviewService {

    @Autowired
    private JobRepository jobRepository;
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    private static final List<String> CITIES = Arrays.asList("北京", "上海", "广州");
    
    // 定义职位类别关键词映射表，用于归类不同类型的职位
    private static final Map<String, List<String>> JOB_CATEGORY_KEYWORDS = new HashMap<>();
    
    static {
        // 后端开发类
        JOB_CATEGORY_KEYWORDS.put("后端开发", Arrays.asList(
            "java", "spring", "springboot", "微服务", "mybatis", 
            "python", "django", "flask", "爬虫", 
            "go", "golang", 
            "php", "laravel", "thinkphp", 
            "c++", "c/c++", "qt", "mfc",
            "后端", "服务端", "dba", "数据库", "架构师", "研发", "开发工程师"
        ));
        
        // 前端开发类
        JOB_CATEGORY_KEYWORDS.put("前端开发", Arrays.asList(
            "前端", "web前端", "javascript", "js", "html", "css", "vue", "react", "angular", "h5", "web开发"
        ));
        
        // 移动端开发
        JOB_CATEGORY_KEYWORDS.put("移动端开发", Arrays.asList(
            "android", "安卓", "ios", "objective-c", "swift", "flutter", "移动端", "app开发", "小程序"
        ));
        
        // 数据分析/挖掘
        JOB_CATEGORY_KEYWORDS.put("数据分析", Arrays.asList(
            "数据分析", "大数据", "hadoop", "spark", "bi", "tableau", "数仓", "etl", "分析师", "数据挖掘"
        ));
        
        // 人工智能/算法
        JOB_CATEGORY_KEYWORDS.put("算法工程师", Arrays.asList(
            "算法", "机器学习", "人工智能", "深度学习", "ai", "nlp", "cv", "图像识别", "自然语言处理", "推荐系统"
        ));
        
        // 测试/运维
        JOB_CATEGORY_KEYWORDS.put("测试运维", Arrays.asList(
            "测试", "自动化测试", "功能测试", "性能测试", "运维", "devops", "linux", "网络工程", "系统运维", "网络安全"
        ));
        
        // 产品经理
        JOB_CATEGORY_KEYWORDS.put("产品经理", Arrays.asList(
            "产品", "产品经理", "产品专家", "产品总监", "产品策略", "产品设计", "需求分析", "产品运营"
        ));
        
        // 设计类
        JOB_CATEGORY_KEYWORDS.put("UI/UX设计", Arrays.asList(
            "ui", "设计师", "交互设计", "ui/ux", "视觉设计", "平面设计", "用户体验", "美工", "创意设计"
        ));
        
        // 运营类
        JOB_CATEGORY_KEYWORDS.put("运营", Arrays.asList(
            "运营", "内容运营", "用户运营", "活动运营", "社区运营", "新媒体运营", "电商运营", "游戏运营", "产品运营",
            "策略运营", "流量运营", "渠道运营"
        ));
        
        // 市场/销售
        JOB_CATEGORY_KEYWORDS.put("市场销售", Arrays.asList(
            "市场", "销售", "营销", "商务", "客户", "市场推广", "品牌", "市场营销", "策划", "品牌营销",
            "销售经理", "大客户", "商务拓展", "客户经理"
        ));
        
        // 游戏开发/策划
        JOB_CATEGORY_KEYWORDS.put("游戏开发", Arrays.asList(
            "游戏", "游戏策划", "游戏制作", "游戏开发", "游戏设计", "游戏美术", "游戏系统", "游戏数值", "引擎"
        ));
        
        // 法务/HR/行政
        JOB_CATEGORY_KEYWORDS.put("行政人事", Arrays.asList(
            "法务", "人力资源", "hr", "行政", "招聘", "培训师", "法律", "人事", "行政助理", "前台", "人力资源"
        ));
    }

    @Override
    public TotalJobsVO getTotalJobs() {
        // 获取总职位数
        long totalJobs = jobRepository.count();
        
        // 获取各城市职位数
        Map<String, Long> cityDistribution = new HashMap<>();
        for (String city : CITIES) {
            long count = jobRepository.countBy工作城市(city);
            cityDistribution.put(city, count);
        }
        
        return new TotalJobsVO(totalJobs, cityDistribution);
    }

    @Override
    public SummaryVO getSummary() {
        List<CityOverview> cityOverviews = new ArrayList<>();
        
        for (String city : CITIES) {
            // 获取城市职位数
            long jobCount = jobRepository.countBy工作城市(city);
            
            // 获取城市平均薪资
            String avgSalary = calculateAvgSalary(city);
            
            // 获取热门职位
            List<HotPosition> hotPositions = getHotPositions(city);
            
            CityOverview cityOverview = new CityOverview(city, jobCount, avgSalary, hotPositions);
            cityOverviews.add(cityOverview);
        }
        
        return new SummaryVO(cityOverviews);
    }
    
    /**
     * 计算城市平均薪资
     * @param city 城市名称
     * @return 平均薪资字符串
     */
    private String calculateAvgSalary(String city) {
        List<Job> jobs = jobRepository.findBy工作城市(city);
        
        // 提取薪资范围并计算平均值
        double totalMin = 0;
        double totalMax = 0;
        int validCount = 0;
        
        for (Job job : jobs) {
            String salary = job.get薪资待遇();
            if (salary != null && !salary.isEmpty()) {
                // 处理薪资格式，如"20k-40k"
                try {
                    String[] parts = salary.toLowerCase().replace("k", "").split("-");
                    if (parts.length == 2) {
                        double min = Double.parseDouble(parts[0]);
                        double max = Double.parseDouble(parts[1]);
                        totalMin += min;
                        totalMax += max;
                        validCount++;
                    }
                } catch (Exception e) {
                    // 忽略无法解析的薪资
                }
            }
        }
        
        if (validCount > 0) {
            double avgSalary = (totalMin + totalMax) / (2 * validCount);
            return String.format("%.1fk", avgSalary);
        } else {
            return "未知";
        }
    }
    
    /**
     * 获取城市热门职位
     * @param city 城市名称
     * @return 热门职位列表
     */
    private List<HotPosition> getHotPositions(String city) {
        // 获取该城市的所有职位
        List<Job> cityJobs = jobRepository.findBy工作城市(city);
        
        // 统计每种职位类别出现的次数
        Map<String, Integer> categoryCount = new HashMap<>();
        // 记录每种职位类别的薪资总和
        Map<String, List<Double>> categorySalaries = new HashMap<>();
        
        for (Job job : cityJobs) {
            String positionName = job.get职位名字();
            if (positionName != null && !positionName.isEmpty()) {
                // 将职位名称转为小写以便匹配
                String lowerName = positionName.toLowerCase();
                
                // 匹配该职位属于哪些职位类别
                boolean matched = false;
                for (Map.Entry<String, List<String>> entry : JOB_CATEGORY_KEYWORDS.entrySet()) {
                    String category = entry.getKey();
                    List<String> keywords = entry.getValue();
                    
                    // 检查职位名称是否包含该类别的关键词
                    for (String keyword : keywords) {
                        if (lowerName.contains(keyword.toLowerCase())) {
                            // 增加该职位类别的计数
                            categoryCount.put(category, categoryCount.getOrDefault(category, 0) + 1);
                            
                            // 添加该职位的薪资到对应职位类别的薪资列表
                            String salary = job.get薪资待遇();
                            if (salary != null && !salary.isEmpty()) {
                                try {
                                    String[] parts = salary.toLowerCase().replace("k", "").split("-");
                                    if (parts.length == 2) {
                                        double min = Double.parseDouble(parts[0]);
                                        double max = Double.parseDouble(parts[1]);
                                        double avg = (min + max) / 2;
                                        
                                        if (!categorySalaries.containsKey(category)) {
                                            categorySalaries.put(category, new ArrayList<>());
                                        }
                                        categorySalaries.get(category).add(avg);
                                    }
                                } catch (Exception e) {
                                    // 忽略无法解析的薪资
                                }
                            }
                            
                            matched = true;
                            break;
                        }
                    }
                    
                    if (matched) {
                        break; // 一个职位只归类到一个类别
                    }
                }
                
                // 如果没有匹配到任何类别，归为"其他"类别
                if (!matched) {
                    categoryCount.put("其他职位", categoryCount.getOrDefault("其他职位", 0) + 1);
                    
                    String salary = job.get薪资待遇();
                    if (salary != null && !salary.isEmpty()) {
                        try {
                            String[] parts = salary.toLowerCase().replace("k", "").split("-");
                            if (parts.length == 2) {
                                double min = Double.parseDouble(parts[0]);
                                double max = Double.parseDouble(parts[1]);
                                double avg = (min + max) / 2;
                                
                                if (!categorySalaries.containsKey("其他职位")) {
                                    categorySalaries.put("其他职位", new ArrayList<>());
                                }
                                categorySalaries.get("其他职位").add(avg);
                            }
                        } catch (Exception e) {
                            // 忽略无法解析的薪资
                        }
                    }
                }
            }
        }
        
        // 转换为HotPosition列表
        List<HotPosition> hotPositions = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : categoryCount.entrySet()) {
            String category = entry.getKey();
            int count = entry.getValue();
            
            // 计算该职位类别的平均薪资
            String avgSalary = "未知";
            if (categorySalaries.containsKey(category) && !categorySalaries.get(category).isEmpty()) {
                List<Double> salaries = categorySalaries.get(category);
                double sum = 0;
                for (Double salary : salaries) {
                    sum += salary;
                }
                double avg = sum / salaries.size();
                avgSalary = String.format("%.0fk", avg);
            }
            
            hotPositions.add(new HotPosition(category, count, avgSalary));
        }
        
        // 按照职位数量降序排序
        hotPositions.sort((p1, p2) -> p2.getCount() - p1.getCount());
        
        // 返回前5个热门职位
        return hotPositions.stream().limit(5).collect(Collectors.toList());
    }
    
    /**
     * 计算特定职位的平均薪资
     * @param city 城市名称
     * @param position 职位名称
     * @return 平均薪资字符串
     */
    private String calculatePositionAvgSalary(String city, String position) {
        // 使用聚合操作计算特定职位的平均薪资
        MatchOperation matchOperation = Aggregation.match(
                Criteria.where("工作城市").is(city).and("职位名字").is(position));
        
        GroupOperation groupOperation = Aggregation.group("职位名字")
                .first("薪资待遇").as("salary");
        
        Aggregation aggregation = Aggregation.newAggregation(
                matchOperation,
                groupOperation
        );
        
        AggregationResults<Map> results = mongoTemplate.aggregate(
                aggregation, "jobs", Map.class);
        
        List<Map> resultList = results.getMappedResults();
        if (!resultList.isEmpty()) {
            Map result = resultList.get(0);
            String salary = (String) result.get("salary");
            
            if (salary != null && !salary.isEmpty()) {
                try {
                    String[] parts = salary.toLowerCase().replace("k", "").split("-");
                    if (parts.length == 2) {
                        double min = Double.parseDouble(parts[0]);
                        double max = Double.parseDouble(parts[1]);
                        double avg = (min + max) / 2;
                        return String.format("%.0fk", avg);
                    }
                } catch (Exception e) {
                    // 忽略无法解析的薪资
                }
            }
        }
        
        return "未知";
    }
} 